import torch
import matplotlib.pyplot as plt

# 未知的规律
# -----------------散点图------------------
x = torch.linspace(-1, 1, 40)
y = -0.4 * x ** 2

plt.plot(x, y, 'ro')


# -----------------激活函数-------------------
def sigmoid(x): # 0~1
    return 1 / (1 + torch.exp(-x))


def tanh(x): # -1~1
    return (torch.exp(x) - torch.exp(-x)) / (torch.exp(x) + torch.exp(-x))


# -----------------预测线--------------------
w_predict = torch.tensor(0.1, requires_grad=True)  # 预测的w
b_predict = torch.tensor(0.2, requires_grad=True)  # 预测的b

y_predict = tanh(w_predict * x + b_predict)
line, = plt.plot(x.detach().numpy(), y_predict.detach().numpy(), 'b--')

# ------------------不断改变斜率,查看e的变化-----
epochs = 100  # w改变一百次
for epoch in range(epochs):
    y_predict = tanh(w_predict * x + b_predict)
    # 预测线不断改变
    line.set_data(x.detach().numpy(), y_predict.detach().numpy())
    # ------------------衡量预测线的准确率---------
    e = (y_predict - y) ** 2
    print(torch.mean(e))
    # 使用损失函数开启整个求导过程
    torch.mean(e).backward()
    # 设置不叠加求导的区域
    with torch.no_grad():
        slope_w = w_predict.grad
        slope_b = b_predict.grad
        w_predict -= torch.mean(slope_w) * 0.1
        b_predict -= torch.mean(slope_b) * 0.1
        # 清空本次的计算导数
        w_predict.grad.zero_()
        b_predict.grad.zero_()
    # 设置延迟时间
    plt.pause(0.5)
